#include <bits/stdc++.h>
#define INF 0x7fffffff
#define MAXN 300023
using namespace std;

inline void File_Read() {
#ifdef MYLAB
	freopen("in.txt", "r", stdin);
#endif
}

inline int get_num() {
	int k = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar())if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) k = k * 10 + c - '0';
	return k * f;
}

int n, cnt, head[MAXN], a[MAXN];

struct edge{
	int to, ne;
	edge(){;}
	edge(int to_, int ne_) {
		to = to_;
		ne = ne_;
	}
}e[MAXN << 1];

inline void addedge(int fr, int to) {
	e[++cnt] = edge(to, head[fr]), head[fr] = cnt;
	e[++cnt] = edge(fr, head[to]), head[to] = cnt; 
}

priority_queue <int> pq, del;
 
inline void autoremove() {
    while(!pq.empty() && !del.empty() && pq.top() == del.top()){
        pq.pop();
        del.pop();
    }
} 

inline void insert(int x) {
    pq.push(x);
    autoremove();
}

inline void remove(int x) {
    del.push(x);
    autoremove();
}

int main() {
	File_Read();
	n = get_num();
	for(int i = 1; i <= n; i++) {
		a[i] = get_num();
        insert(a[i]);
	}
	for(int i = 1; i < n; i++) {
		int fr = get_num();
		int to = get_num();
		addedge(fr, to);
	}
    int ans = INF;
    for(int x = 1; x <= n; x++) {
        int now = a[x];
        remove(a[x]);
        for(int i = head[x]; i; i = e[i].ne) {
            int y = e[i].to;
            now = max(now , a[y] + 1);
            remove(a[y]);
        }
        if(!pq.empty()) now = max(now, pq.top() + 2);
        ans = min(ans, now);
        insert(a[x]);
        for(int i = head[x]; i; i = e[i].ne) {
            insert(a[e[i].to]);
        }
    }
    printf("%d\n", ans);
	return 0;
}
